home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 2 / Atari Mega Archive CD - Volume 2.iso / minix / up1510b.tgz / up1510b / src / commands / atari / cc.c < prev    next >
C/C++ Source or Header  |  1990-07-15  |  17KB  |  842 lines

  1. /*
  2.  * (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
  3.  * See the copyright notice in the file "../Copyright".
  4.  */
  5. /*    Driver for Minix compilers.
  6.     Written june 1987 by Ceriel J.H. Jacobs, partly derived from old
  7.     cc-driver, written by Erik Baalbergen.
  8.     This driver is mostly table-driven, the table being in the form of
  9.     some global initialized structures.
  10. */
  11.     
  12. #include <errno.h>
  13. #include <signal.h>
  14.  
  15. /*
  16.  * For all program paths (so not the other files, like libraries) that
  17.  * start with "/usr/" and are executable according to access(..., 1),
  18.  * the leading "/usr" is stripped off.
  19.  */
  20.  
  21. #define SHELL        "/bin/sh"
  22.  
  23. #define AS        "/usr/bin/as"
  24. #define CEM        "/usr/lib/cem"
  25. #define CG        "/usr/lib/cg"
  26. #define PP        "/usr/lib/cpp"
  27. #define CRT        "/usr/lib/crtso.o"
  28. #define CV        "/usr/lib/cv"
  29. #define PC        "/usr/lib/em_pc"
  30. #define END        "/usr/lib/end.o"
  31. #define LD        "/usr/lib/ld"
  32. #define LIBC        "/usr/lib/libc.a"
  33. #define LIBP        "/usr/lib/libp.a"
  34. #define OPT        "/usr/lib/opt"
  35. #define PRT        "/usr/lib/prtso.o"
  36. #define LIBPREFIX    "/usr/lib/lib"
  37.  
  38. #define PEM        "-R/usr/lib/pem"
  39. #define PC_ERR        "-r/usr/lib/pc_errors"
  40.  
  41. /*    every pass that this program knows about has associated with it
  42.     a structure, containing such information as its name, where it
  43.     resides, the flags it accepts, and the like.
  44. */
  45. struct passinfo {
  46.     char *p_name;        /* name of this pass */
  47.     char *p_path;        /* where is it */
  48.     char *p_from;        /* suffix of source (comma-separated list) */
  49.     char *p_to;        /* suffix of destination */
  50.     char *p_acceptflags;    /* comma separated list; format:
  51.                        flag
  52.                        flag*
  53.                        flag=xxx
  54.                     flag*=xxx[*]
  55.                    where a star matches a, possibly empty, 
  56.                    string
  57.                 */
  58.     int  p_flags;
  59. #define INPUT    01        /* needs input file as argument */
  60. #define OUTPUT    02        /* needs output file as argument */
  61. #define LOADER    04        /* this pass is the loader */
  62. #define STDIN    010        /* reads from standard input */
  63. #define STDOUT    020        /* writes on standard output */
  64. #define SOURCE    040        /* give source file name as last argument
  65.                    (hack for pc)
  66.                 */
  67. #define O_OUTPUT 0100        /* -o outputfile, hack for as */
  68. #define PREPALWAYS    0200    /* always to be preprocessed */
  69. #define PREPCOND    0400    /* preprocessed when starting with '#' */
  70. };
  71.  
  72. #define MAXHEAD    7
  73. #define MAXTAIL    4
  74. #define MAXPASS    7
  75.  
  76. /*    Every language handled by this program has a "compile" structure
  77.     associated with it, describing the start-suffix, how the driver for
  78.     this language is called, which passes must be called, which flags
  79.     and arguments must be passed to these passes, etc.
  80.     The language is determined by the suffix of the argument program.
  81.     However, if this suffix does not determine a language (DEFLANG),
  82.     the callname is used.
  83.     Notice that the 's' suffix does not determine a language, because
  84.     the input file could have been derived from f.i. a C-program.
  85.     So, if you use "cc x.s", the C-runtime system will be used, but if
  86.     you use "as x.s", it will not.
  87. */
  88. struct compile {
  89.     char *c_suffix;        /* starting suffix of this list of passes */
  90.     char *c_callname;    /* affects runtime system loaded with program */
  91.     struct pass {
  92.         char *pp_name;        /* name of the pass */
  93.         char *pp_head[MAXHEAD];    /* args in front of filename */
  94.         char *pp_tail[MAXTAIL];    /* args after filename */
  95.     } c_passes[MAXPASS];
  96.     int  c_flags;
  97. #define DEFLANG        010    /* this suffix determines a language */
  98. };
  99.  
  100. struct passinfo passinfo[] = {
  101.     { "cpp", PP, 0, "i", "I*,D*,U*", INPUT|STDOUT },
  102.     { "cem", CEM, "i,c", "k", "R,p,w,T*,I*,D*,U*", INPUT|OUTPUT },
  103.     { "pc", PC, "i,p", "k", "L,p,w,e,E,T*,{*", INPUT|OUTPUT|SOURCE|PREPCOND },
  104.     { "opt", OPT, "k", "m", "LIB=L", STDIN|STDOUT },
  105.     { "cg", CG, "m", "s", "O=p4", INPUT|OUTPUT },
  106.     { "as", AS, "i,s", "o", "T*", INPUT|O_OUTPUT|PREPCOND },
  107.     { "ld", LD, "o", "out", "r,s", INPUT|LOADER },
  108.     { "cv", CV, "out", 0, "", INPUT|OUTPUT },    /* must come after loader */
  109.     { 0}
  110. };
  111.  
  112. struct compile passes[] = {
  113. {    "c", "cc", 
  114.     {    { "cem", {"-L"}, {0} },
  115.         { "opt", {0}, {0} },
  116.         { "cg", {0}, {0} },
  117.         { "as", {"-"}, {0} },
  118.         { "ld", {"-c", "-a0:2", "-a1:2", "-a2:2", "-a3:2", CRT}, 
  119.               {LIBC, END}},
  120.         { "cv", {0}, {0} }
  121.     },
  122.     DEFLANG
  123. },
  124. {    "p", "pc",
  125.     {    { "pc", { PEM, PC_ERR, "-Vw2i2j2p2f8l4" }, {0} },
  126.         { "opt", {0}, {0} },
  127.         { "cg", {0}, {0} },
  128.         { "as", {"-"}, {0} },
  129.         { "ld", {"-c", "-a0:2", "-a1:2", "-a2:2", "-a3:2", PRT}, 
  130.               {LIBP, LIBC,
  131.                END}},
  132.         { "cv", {0}, {0} }
  133.     },
  134.     DEFLANG
  135. },
  136. {    "s", "as",
  137.     {    { "as", {0}, {0}}}, 0 },
  138. {    0}
  139. };
  140.  
  141. #define MAXARGC    128    /* maximum number of arguments allowed in a list */
  142. #define USTR_SIZE    64    /* maximum length of string variable */
  143.  
  144. typedef char USTRING[USTR_SIZE];
  145.  
  146. struct arglist {
  147.     int al_argc;
  148.     char *al_argv[MAXARGC];
  149. };
  150.  
  151. struct arglist CALLVEC[2];
  152.  
  153. int kids[] = {-1, -1};
  154.  
  155. char *o_FILE = "a.out"; /* default name for executable file */
  156.  
  157. #define init(a)        ((a)->al_argc = 1)
  158. #define cleanup(str)        (str && remove(str))
  159. #define library(nm) \
  160.     mkstr(alloc((unsigned int)strlen(nm) + strlen(LIBPREFIX) + 7), \
  161.         LIBPREFIX, nm, ".a")
  162.  
  163. char *ProgCall = 0;
  164.  
  165. int RET_CODE = 0;
  166.  
  167. char *stopsuffix;
  168. int v_flag = 0;
  169. int t_flag = 0;
  170. int noexec = 0;
  171.  
  172. char *mkstr();
  173. char *alloc();
  174. char *process();
  175. char *strcpy(), *strcat();
  176.  
  177. USTRING curfil;
  178. USTRING newfil;
  179. struct arglist SRCFILES;
  180. struct arglist LDFILES;
  181. struct arglist GEN_LDFILES;
  182. struct arglist FLAGS;
  183.  
  184. char *tmpdir = "/tmp";
  185. char tmpname[64];
  186.  
  187. struct compile *compbase;
  188. struct pass *loader;
  189. struct passinfo *loaderinfo;
  190. char *source;
  191.  
  192. trapcc(sig)
  193.     int sig;
  194. {
  195.     signal(sig, SIG_IGN);
  196.     if (kids[0] != -1) kill(kids[0], sig);
  197.     if (kids[1] != -1) kill(kids[1], sig);
  198.     cleanup(newfil);
  199.     cleanup(curfil);
  200.     exit(1);
  201. }
  202.  
  203. main(argc, argv)
  204.     char *argv[];
  205. {
  206.     char *str;
  207.     char **argvec;
  208.     int count;
  209.     char *file;
  210.  
  211.     ProgCall = *argv++;
  212.  
  213.     mkbase();
  214.  
  215.     signal(SIGHUP, trapcc);
  216.     signal(SIGINT, trapcc);
  217.     signal(SIGQUIT, trapcc);
  218.     while (--argc > 0) {
  219.         if (*(str = *argv++) != '-') {
  220.             append(&SRCFILES, str);
  221.             continue;
  222.         }
  223.  
  224.         switch (str[1]) {
  225.  
  226.         case 'c':
  227.             stopsuffix = "o";
  228.             break;
  229.         case 'F':
  230.             break;
  231.         case 'l':
  232.             append(&SRCFILES, library(&str[2]));
  233.             break;
  234.         case 'o':
  235.             if (argc-- >= 0)
  236.                 o_FILE = *argv++;
  237.             break;
  238.         case 'S':
  239.             stopsuffix = "s";
  240.             break;
  241.         case 'v':
  242.             v_flag++;
  243.             if (str[2] == 'n')
  244.                 noexec = 1;
  245.             break;
  246.         case 't':
  247.             /* save temporaries */
  248.             t_flag++;
  249.             break;
  250.         case 'T':
  251.             tmpdir = &str[2];
  252.             /*FALLTHROUGH*/
  253.         default:
  254.             append(&FLAGS, str);
  255.  
  256.         }
  257.     }
  258.  
  259.     mktempname(tmpname);
  260.  
  261.     count = SRCFILES.al_argc;
  262.     argvec = &(SRCFILES.al_argv[0]);
  263.  
  264.     while (count-- > 0) {
  265.  
  266.         file = *argvec++;
  267.         source = file;
  268.  
  269.         if (SRCFILES.al_argc > 1) {
  270.             write(1, file, strlen(file));
  271.             write(1, ":\n", 2);
  272.         }
  273.  
  274.         file = process(file, 1);
  275.     
  276.         if (file && ! stopsuffix) append(&LDFILES, file);
  277.     }
  278.  
  279.     clean(&SRCFILES);
  280.  
  281.     /* loader ... */
  282.     if (RET_CODE == 0 && LDFILES.al_argc > 0) {
  283.         register struct passinfo *pp = passinfo;
  284.  
  285.         while (!(pp->p_flags & LOADER)) pp++;
  286.         mkstr(newfil, tmpname, pp->p_to, "");
  287.         callld(&LDFILES, !((pp+1)->p_name) ? o_FILE : newfil, loader, pp);
  288.         if (RET_CODE == 0) {
  289.             register int i = GEN_LDFILES.al_argc;
  290.  
  291.             while (i-- > 0) {
  292.                 remove(GEN_LDFILES.al_argv[i]);
  293.                 free(GEN_LDFILES.al_argv[i]);
  294.             }
  295.             if ((++pp)->p_name) {
  296.                 process(newfil, 0);
  297.             }
  298.         }
  299.     }
  300.     exit(RET_CODE);
  301. }
  302.  
  303. remove(str)
  304.     char *str;
  305. {
  306.     if (t_flag)
  307.         return;
  308.     if (v_flag) {
  309.         prs("rm ");
  310.         prs(str);
  311.         prs("\n");
  312.     }
  313.     if (noexec)
  314.         return;
  315.     unlink(str);
  316. }
  317.  
  318. char *
  319. alloc(u)
  320.     unsigned u;
  321. {
  322.     char *malloc();
  323.     register char *p = malloc(u);
  324.  
  325.     if (p == 0) panic("no space\n");
  326.     return p;
  327. }
  328.  
  329. append(al, arg)
  330.     struct arglist *al;
  331.     char *arg;
  332. {
  333.     char *a = alloc((unsigned) (strlen(arg) + 1));
  334.  
  335.     strcpy(a, arg);
  336.     if (al->al_argc >= MAXARGC)
  337.         panic("argument list overflow\n");
  338.     al->al_argv[(al->al_argc)++] = a;
  339. }
  340.  
  341. concat(al1, al2)
  342.     struct arglist *al1, *al2;
  343. {
  344.     register i = al2->al_argc;
  345.     register char **p = &(al1->al_argv[al1->al_argc]);
  346.     register char **q = &(al2->al_argv[0]);
  347.  
  348.     if ((al1->al_argc += i) >= MAXARGC)
  349.         panic("argument list overflow\n");
  350.     while (i-- > 0)
  351.         *p++ = *q++;
  352. }
  353.  
  354. char *
  355. mkstr(dst, arg1, arg2, arg3)
  356.     char *dst, *arg1, *arg2, *arg3;
  357. {
  358.     register char *p;
  359.     register char *q = dst;
  360.  
  361.     p = arg1;
  362.     while (*q++ = *p++);
  363.     q--;
  364.     p = arg2;
  365.     while (*q++ = *p++);
  366.     q--;
  367.     p = arg3;
  368.     while (*q++ = *p